package com.platform.gateway.config;

import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixObservableCommand;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * 全局配置
 *
 * @author baohuajie (baohuajie134@163.com)
 * @create 2021 01 01 10:54
 * @since 1.0.0
 */
@Configuration
public class GatewayConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    IRule iRule(){
//		return new RandomRule(); //分配策略：随机选择一个server
//        return new BestAvailableRule(); //分配策略：选择一个   最小的并发请求的server，逐个考察Server，如果Server被tripped了，则忽略
        return new RoundRobinRule(); //分配策略：轮询选择，轮询index，选择index对应位置的server
//        return new WeightedResponseTimeRule(); //分配策略：根据响应时间分配一个weight(权重)，响应时间越长，weight越小，被选中的可能性越低
//        return new ZoneAvoidanceRule(); //分配策略：复合判断server所在区域的性能和server的可用性选择server
//        return new RetryRule(); //分配策略：对选定的负载均衡策略机上重试机制，在一个配置时间段内当选择server不成功，则一直尝试使用subRule的方式选择一个可用的server
    }

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {

        RouteLocator routeLocator = builder.routes()
                .route("cim-service", r -> r.path("/cim-service/**").filters(f -> f.hystrix(config -> {
                    config.setName("cim-service-hystrix");
                    config.setSetter(cimSetter());
                    config.setFallbackUri("forward:/cim/fallback");
                }).stripPrefix(1)).uri("lb://cim-service")).build();
        return routeLocator;
    }

    private static HystrixObservableCommand.Setter cimSetter(){
        HystrixCommandGroupKey hystrixCommandGroupKey = HystrixCommandGroupKey.Factory.asKey("cim-service-group-key");
        HystrixCommandProperties.Setter propertiesSetter = HystrixCommandProperties.Setter().withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
                .withExecutionTimeoutEnabled(true)
                .withExecutionTimeoutInMilliseconds(100000)
                .withExecutionIsolationThreadInterruptOnTimeout(true);


        HystrixObservableCommand.Setter setter = HystrixObservableCommand.Setter.withGroupKey(hystrixCommandGroupKey)
                .andCommandPropertiesDefaults(propertiesSetter);
        return setter;
    }

}
